#include <Arduino.h>
#include <ArduinoJson.h>
#include <birdwater.h>
#include <MqttReq.h>

int postid = 0;

int ATWaitOK(int ms)
{
  int t0 = 0;
  t0 = millis() + ms; 

  ReceiveState.OK = 0;
  do{

    if (millis() > t0)
    {
      Serial.println("ReceiveState.OK time out!");
      ReceiveState.ErrNum++;
      return 0;
    }

    MQTTDispack();
  }while(ReceiveState.OK == 0);
  
  ReceiveState.ErrNum = 0;
  Serial.println("ReceiveState.OK!");
  return 1;
}

int ATWaitReady(int ms)
{
  int t0 = 0;
  t0 = millis() + ms; 

  ReceiveState.ready = 0;
  do{

    if (millis() > t0)
    {
      Serial.println("ReceiveState.ready time out!");
      return 0;
    }

    MQTTDispack();
  }while(ReceiveState.ready == 0);
  
  Serial.println("ReceiveState.ready!");
  return 1;
}

int ATWaitWIFICONNECTED(int ms)
{
  int t0 = 0;
  t0 = millis() + ms; 

  ReceiveState.WIFICONNECTED = 0;
  do{

    if (millis() > t0)
    {
      Serial.println("ReceiveState.WIFICONNECTED time out!");
      return 0;
    }

    MQTTDispack();
  }while(ReceiveState.WIFICONNECTED == 0);
  
  Serial.println("ReceiveState.WIFICONNECTED!");
  return 1;
}

int ATWaitSmartConfig(int ms)
{
  int t0 = 0;
  t0 = millis() + ms; 

  ReceiveState.SmartconfigConnected = 0;
  do{

    if (millis() > t0)
    {
      Serial.println("ReceiveState.SmartconfigConnected time out!");
      return 0;
    }

    MQTTDispack();
  }while(ReceiveState.SmartconfigConnected == 0);
  
  Serial.println("ReceiveState.SmartconfigConnected!");
  return 1;
}
//网络配置
unsigned int MqttConected = 0;

/*

*/
void MQTTInit(void){
  String outString="";
  outString = String("AT+MQTTSUB=0,\"$sys/") + PRODUCT_NAME + "/" + DEVICE_NAME + "/thing/property/set\",1"; //注册属性设置
  Serial1.println(outString);
  ATWaitOK(2000);

  outString = String("AT+MQTTSUB=0,\"$sys/")+ PRODUCT_NAME + "/" + DEVICE_NAME + "/thing/service/StartWaterPump/invoke\",1"; //注册属性设置
  Serial1.println(outString);
  ATWaitOK(2000); 

  Serial.println("mqtt init!");
}
unsigned int MQTTConnectFun(void) {
  int res = 0;

  delay(2000); 
  Serial1.printf("AT+RST");  //
  Serial1.println();  
  
  res = ATWaitOK(10000);
  res = ATWaitReady(10000);

  Serial1.printf("AT+CWMODE=1");  //
  Serial1.println();

  ATWaitOK(2000);

  Serial1.printf("AT+CWDHCP=1,1");  //启动DHCP
  Serial1.println();

  ATWaitOK(2000);

  
  Serial1.printf("AT+CWSTATE?");  //查询Wi-Fi状态和Wi-Fi信息
  Serial1.println();

  ATWaitOK(2000);

  Serial1.printf("AT+CWJAP");  //连接AP
  Serial1.println();

  ATWaitOK(2000);

  String outString="";
  outString = String("AT+MQTTUSERCFG=0,1")+",\""+DEVICE_NAME+"\""+",\""+PRODUCT_NAME+"\""+",\""+ DEVICE_TOKEN +"\""+",0,0,\"\"";
  Serial1.println(outString);
  ATWaitOK(2000);  

  // Serial1.printf("AT+MQTTCONN=0,\"mqtts.heclouds.com\",1883,1");  //连接服务器
  Serial1.printf("AT+MQTTCONN=0,\"183.230.40.96\",1883,1");  //连接服务器
  Serial1.println();

  res = ATWaitOK(10000);

  return res;
}


void MQTTStartConfgFun(void)
{
  delay(2000);
  Serial1.println("AT+CWSTARTSMART=3");    
  ATWaitOK(1000);   
  ATWaitSmartConfig(60000);

  Serial1.println("AT+CWSTOPSMART");    
  ATWaitOK(1000);  
}


void MQTTset_reply(String DataOneJSON)
{
  DataOneJSON.replace("\"","\\\"");
  DataOneJSON.replace(",","\\,");

  String outString="";
  String topic =String("\"$sys/9BXG6M4BH5/") + DEVICE_NAME + "/thing/property/set_reply\"";
  outString = "AT+MQTTPUB=0,"+topic+","+"\""+DataOneJSON+"\""+",1,0";

  Serial1.println(outString);
  ATWaitOK(2000);
}
void MQTTinvoke_reply(String DataOneJSON)
{
  DataOneJSON.replace("\"","\\\"");
  DataOneJSON.replace(",","\\,");

  String outString="";
  String topic =String("\"$sys/9BXG6M4BH5/") + DEVICE_NAME + "/thing/service/StartWaterPump/invoke_reply\"";
  
  outString = "AT+MQTTPUB=0,"+topic+","+("\""+DataOneJSON+"\"")+",1,0";
  Serial1.println(outString);
  ATWaitOK(2000);

}

void MQTTpost(String DataOneJSON)
{
  DataOneJSON.replace("\"","\\\"");
  DataOneJSON.replace(",","\\,");

  String outString="";                   
  String topic =String("\"$sys/9BXG6M4BH5/") + DEVICE_NAME + "/thing/property/post\"";

  outString = "AT+MQTTPUB=0,"+topic+","+"\""+DataOneJSON+"\""+",1,0";

  Serial1.println(outString);
  ATWaitOK(5000);


}


//云端控制 MQTT
//INIT=0,NETCONECT,MQTTUSERCFG,MQTTCONN,MQTTSUB,MQTTPUB}
BirdWaterConfig g_BirdWaterConfigBk;

void MQTTUpdate(void) {
  static int timedelay = 0;
  
  int DataValid = 0;
  // return;
  if (millis() < timedelay)
  {
    return;
  }
  timedelay = millis()+1000;
  int CurrentWaterVolume;
  // CurrentWaterVolume = (g_BirdWaterConfig.g_waterEN > 0) ? (g_BirdWaterConfig.g_WaterTime : 0);
  CurrentWaterVolume = g_BirdWaterConfig.g_WaterTime;
  // 属性（R）：电源电压，工作状态，浇水运行时间
  // 属性（RW）：浇水间隔时间，浇水任务时间
  int g_dc12v = g_BirdWaterConfig.wakeupsourse;         //电源电压-唤醒原因
  int g_WorkState = g_BirdWaterConfig.g_WorkState;      //工作状态-水泵
  int g_Runtime = (millis() / 1000 * 100 / 3600) % 10000;        //0.01 小时 //浇水运行时间

  int g_WaterTime = g_BirdWaterConfig.g_WaterTime;  //浇水任务时间
  int g_SleepTime = g_BirdWaterConfig.g_SleepTime/3600;  //浇水间隔时间  

  g_BirdWaterConfig.g_Runtime = g_Runtime;

  Serial.printf("\n状态信息:工作模式为%d,网络状态为%d,按键状态为%d,电压为%d,继电器为%d,运行时间为%d。",g_BirdWaterConfig.g_WorkState,ReceiveState.ready,g_BirdWaterConfig.g_Key,g_dc12v,g_WorkState,g_Runtime);
  Serial.printf("\n属性信息:最大工作时间为%d,定时时间为%d。\n",g_WaterTime,g_SleepTime);

  if ((g_BirdWaterConfig.g_WorkState == WORK_STATE_STUDY) || (ReceiveState.ready == 0)) {    
    return;
  } else {   
    String substr;
    JsonObject JSparams,JSroot;
    StaticJsonDocument<200> jsonBuffer; //声明一个JsonDocument对象，长度200
    jsonBuffer["id"] = String(postid);          // 字符串  
    JSparams = jsonBuffer.createNestedObject("params"); //添加一个对象节点

    if((postid == 0) || g_BirdWaterConfig.wakeupsourse != g_BirdWaterConfigBk.wakeupsourse)
    {
      JSroot = JSparams.createNestedObject("dc12v"); //添加一个对象节点
      JSroot["value"] = g_BirdWaterConfig.wakeupsourse;
      DataValid++;
    }
    if((postid == 0) || g_BirdWaterConfig.g_PumpOn != g_BirdWaterConfigBk.g_PumpOn)
    {
      JSroot = JSparams.createNestedObject("WorkState"); //添加一个对象节点
      JSroot["value"] = g_BirdWaterConfig.g_PumpOn;
      DataValid++;
    }
    if((postid == 0) || g_BirdWaterConfig.g_WaterTime != g_BirdWaterConfigBk.g_WaterTime)
    {
      JSroot = JSparams.createNestedObject("WaterTime"); //添加一个对象节点
      JSroot["value"] = g_BirdWaterConfig.g_WaterTime;
      DataValid++;
    }

    if((postid == 0) || g_BirdWaterConfig.g_SleepTime != g_BirdWaterConfigBk.g_SleepTime)
    {
      JSroot = JSparams.createNestedObject("SleepTime"); //添加一个对象节点
      JSroot["value"] = g_BirdWaterConfig.g_SleepTime/3600;
      DataValid++;
    }

    if((postid == 0) || g_BirdWaterConfig.g_Runtime != g_BirdWaterConfigBk.g_Runtime)
    {
      JSroot = JSparams.createNestedObject("Runtime"); //添加一个对象节点
      JSroot["value"] = g_BirdWaterConfig.g_Runtime;
      DataValid++;
    }

    memcpy(&g_BirdWaterConfigBk,&g_BirdWaterConfig,sizeof(BirdWaterConfig));
    // void *memcpy(void *destin, void *source, unsigned n)；

    serializeJson(jsonBuffer, substr);  // 序列化JSON数据并导出字符串

    if (DataValid)
    {
      MQTTpost(substr);  
      postid++; 
    }
  }  
}





ReceiveStateType ReceiveState;

void MQTTDispack(void) {
  String inString="";
  char aRxBuffer1;

  while(Serial1.available()>0){
    aRxBuffer1 =  char(Serial1.read());
    
    if (aRxBuffer1 != '\n')
    {
      inString += aRxBuffer1;
    }
    else
    {
      Serial.print("Input String:");
      Serial.println(inString);
      // DebuglogAdd(inString);

      delay(10);
      /* 解码
    +MQTTSUBRECV:0,"$sys/9BXG6M4BH5/ST_001/thing/property/set",69,{"id":"84","version":"1.0","params":{"SleepTime":100,"WaterTime":55}}
      */
      if (inString.startsWith("+MQTTSUBRECV") ) {  
         
          ReceiveState.RECV = 1;    
          if (inString.indexOf("service") >=0 )
          {
            ReceiveState.RECV = 2; 
          }

          int index = inString.indexOf("{");
          String substr = inString.substring(index);
          Serial.println("It's an +MQTTSUBRECV:"+substr); 

           /* 2. 创建一个DynamicJsonDocument对象*/
          /* 计算创建一个DynamicJsonDocument对象将要占用多大的内存空间 */
          const size_t capacity = JSON_OBJECT_SIZE(2) + 30;
          /* 通过计算好的内存空间传入参数创建一个DynamicJsonDocument对象 */
          DynamicJsonDocument doc(capacity);
          
          /* 3. 使用deserializeJson()函数来解析Json数据 */
          DeserializationError error = deserializeJson(doc, substr);
          String id = doc["id"];  
          
          StaticJsonDocument<200> jsonBuffer;   //声明一个JsonDocument对象，长度200


          if (ReceiveState.RECV == 2)
          {
            long State = doc["params"]["State"]; 
            long Time = doc["params"]["Time"]; 
            Serial.printf("State:,%d,Time:,%d",State,Time);
            Serial.println();   

          jsonBuffer["id"] = id;          // 字符串
          jsonBuffer["code"] = 0;      // 浮点数
          jsonBuffer["msg"] =  "ok";     // 字符串
          // JsonObject root = jsonBuffer.createNestedObject("data"); //添加一个对象节点
          // root["Ready"] = ReceiveState.ready;      

          serializeJson(jsonBuffer, substr);  // 序列化JSON数据并导出字符串
          
            if (State == 1)
            {
              g_BirdWaterConfig.g_WorkState = WORK_STATE_WORK;
              g_BirdWaterConfig.g_SSTimer = 0;
            }
            else if (g_BirdWaterConfig.g_WorkState == WORK_STATE_WORK)
            {
              g_BirdWaterConfig.g_WorkState = WORK_STATE_IDLE;
              g_BirdWaterConfig.g_SSTimer = 0;
            }

            MQTTinvoke_reply(substr);      
          }
          else
          {
            long SleepTime = doc["params"]["SleepTime"];
            long WaterTime = doc["params"]["WaterTime"];

            if (error)
            {
              jsonBuffer["code"] = 1000;      // 浮点数
            }
            else
            {
              jsonBuffer["code"] = 200;      // 浮点数
              g_BirdWaterConfig.g_WaterTime = WaterTime;
              g_BirdWaterConfig.g_SleepTime = SleepTime*3600; //小时

              g_BirdWaterConfig.g_WorkState = WORK_STATE_TEST;
              g_BirdWaterConfig.g_SSTimer = 0;
            }
            
            Serial.printf("%d,%d",SleepTime,WaterTime);
            Serial.println();           

          jsonBuffer["id"] = id;          // 字符串
          
          jsonBuffer["msg"] =  "棒棒";     // 字符串
          serializeJson(jsonBuffer, substr);  // 序列化JSON数据并导出字符串
              
          MQTTset_reply(substr);
            
          }
          
      }
      else if (inString.startsWith("OK") ) {  
        ReceiveState.OK = 1;   
        
      }
      else if (inString.startsWith("ready") ) {  
        ReceiveState.ready = 1; 
        
      } 
      else if (inString.startsWith("+MQTTCONNECTED") ) {  
        ReceiveState.ready = 1;         
      }
      else if (inString.startsWith("WIFI GOT IP") ) {  
        ReceiveState.WIFICONNECTED = 1;         
      }
      else if (inString.startsWith("smartconfig connected wifi") ) {  
        //
        ReceiveState.SmartconfigConnected = 1;
      }

      inString = "";

      return; 
    }

    delay(10);      // 延时函数用于等待字符完全进入缓冲区，可以尝试没有延时，输出结果会是什么
  }
}